/**
 * Utility class to manage annotations
 * 
 * @class
 * @extends Biojs
 * 
 * @author <a href="mailto:johncar@gmail.com">John Gomez</a>
 * 
 * @requires <a href='http://blog.jquery.com/2011/09/12/jquery-1-6-4-released/'>jQuery 1.6.4+</a>
 * @dependency <script language="JavaScript" type="text/javascript" src="../biojs/dependencies/jquery/jquery-1.6.4.js"></script>
 * 
 * @param {Object} options 
 *    An object with the options for TagCloud component.
 *    
 * @option {string} sparqlUrl 
 *    URL of the data source
 * 
 * @example
 *    var instance = new Biojs.Annotations({
 *       proxyUrl: '../biojs/dependencies/proxy/proxy.php'
 *    });
 *    
 */
Biojs.Annotations = Biojs.extend (
/** @lends Biojs.Annotations# */
{
	constructor: function (options) {
		// set default topics map
		// it would change on calling up this.applyFilter();
        this._topicsMap = Biojs.Annotations.TOPIC;
	},

	/**
	 * Default values for the options
	 * @name Biojs.Annotations-opt
	 */
	opt: {
		target: "YourOwnDivId",
		sparqlUrl: 'http://virtuoso.idiginfo.org/sparql',
		proxyUrl: 'biojs/dependencies/proxy/proxy.php',
		groupBy: "term",
		filterBy: { field:"topic", value:"uniprot|GO|CHEBI|ICD9|UMLS|fma|MSH|PO|MDDB|NDDF|NDFRT|NCBITaxon" },
		minFrequency: 1
	},
  
	/**
	 * Array containing the supported event names
	 * @name Biojs.Annotations-eventTypes
	 */
	eventTypes: [
	    /**
	     * @name Biojs.Annotations#onDataArrived
	     * @event
	     * @param {function} actionPerformed A function which receives an {@link Biojs.Event} object as argument.
	     * @eventData {Object} source The component which did triggered the event.
	     * @eventData {string} type The name of the event.
	     * @eventData {string} tagName Name of the clicked tag.
	     * @example 
	     * instance.onDataArrived(
	     *    function( e ) {
	     *       alert( "Data received" );
	     *    }
	     * ); 
	     * 
	     */
	    "onDataArrived",
	],
	
	/**
     * Filters the current data. It does not a new request for data.
     * It just filters the already gotten data. 
	 * 
	 * @param {object} filter It must have both members frequency and topics. 
	 *    filter.frequency must be an integer which filters by the minimum frequency.
	 *    filter.topics must be an array containing the name of topics to avoid.
	 * 
	 * @returns {object} Filtered data.
	 * 
	 * @example 
	 * instance.applyFilter({ frequency: 7, topics: ['uniprot','chebi'] });
	 * 
	 */
	applyFilter: function ( filter ) {
		
		if ( filter.hasOwnProperty('frequency') ) {
			this.opt.minFrequency = filter['frequency'];
		}
		
		if ( filter.hasOwnProperty('topics') ) {
			
			this._topicsMap = Biojs.Utils.clone( Biojs.Annotations.TOPIC );
			
			for ( var i in filter.topics ) {
				for ( var t in this._topicsMap ) {
					if ( this._topicsMap[t].shortName == filter.topics[i] ) {
						delete this._topicsMap[t];
					}
				}
			}
		}
		
		delete this._data;
		
		return this.getDataBy( this.opt.groupBy );
		
	},
	
	/**
     * Abort the current Ajax request. 
	 * 
	 * @example 
	 * instance.abort();
	 * 
	 */
	cancelRequest: function() {
		this._request.abort();
	},
	
	/**
     * Retrieves current data grouped by input criteria
	 * 
	 * @param {static} groupingCriteria One of values: Biojs.Annotations.GROUP_BY_TERM, Biojs.Annotations.GROUP_BY_TOPIC
	 * 
	 * @returns {object} Grouped data.
	 * 
	 * @example 
	 * var data = instance.getDataBy( Biojs.Annotations.GROUP_BY_TERM );
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getDataBy: function ( groupingCriteria, value ) {
		return ( groupingCriteria == Biojs.Annotations.GROUP_BY_TERM )? this.getDataByTerm(value) : this.getDataByTopic(value);
	},
	
	/**
     * Retrieves current data grouped by term.
	 * 
	 * @param {string} [term] If provided, data will be filtered by given term
	 * 
	 * @returns {object} Data grouped by term.
	 * 
	 * @example 
	 * var data = instance.getDataByTerm();
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getDataByTerm: function ( term ) {
		if ( this.opt.groupBy != Biojs.Annotations.GROUP_BY_TERM ) {
			this._groupByTerm();
		}
		
		if ( this._data == undefined ) {
			this._groupByTerm();
		}
		
		if ( term != undefined ) {
			for ( var key in this._data ) {
				if ( !( key.toLowerCase() === term.toLowerCase() ) ) delete this._data[key];
			}
		}
		
		return this._data;
	},
	
	/**
     * Retrieves current data grouped by topic.
	 * 
	 * @param {string} [topic] If provided, data will be filtered by given topic name
	 * 
	 * @returns {object} Data grouped by topic.
	 * 
	 * @example 
	 * var data = instance.getDataByTopic();
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getDataByTopic: function ( topic ) {
		if ( this.opt.groupBy != Biojs.Annotations.GROUP_BY_TOPIC ) {
			this._groupByTopic();
		}
		
		if ( this._data == undefined ) {
			this._groupByTopic();
		}
		
		if ( topic != undefined ) {
			for ( var key in this._data ) {
				if ( !( key.toLowerCase() === topic.toLowerCase() ) ) delete this._data[key];
			}
		}
		
		return this._data;
	},
	
	/**
     * Retrieves all the URIs entities.
     * 
	 * @returns {array} List of current URIs entities.
	 * 
	 * @example 
	 * var data = instance.getEntities();
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getAllEntities: function () {
		
		var entities = {};
		var entityURI;
		
		for ( var r in this._dataBindings ) {
			annotation = this._dataBindings[r];
			entityURI = annotation.topic.value;
			entities[ this._digest(entityURI) ] = entityURI; 
        }
		
		return entities;
	},
	
	/**
     * Retrieves a member of current data.
     * 
     * @param {string} key Parameter value to be retrieved.
     * 
	 * @returns {object} Data member
	 * 
	 * @example 
	 * instance.getDataByTopic();
	 * var data = instance.getItem("chebi");
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getItem: function(key) {
		return this._data[key];
	},
	
	/**
     * Retrieves the current data as it was received from server
     * 
     * @param {string} key Parameter value to be retrieved.
     * 
	 * @returns {object} Data member
	 * 
	 * @example 
	 * var data = instance.getRawData();
	 * console.log(data);
	 * alert('Go to console to see the retrieved data');
	 * 
	 */
	getRawData: function () {
		return this._data;
	},
	
	/**
     * Informs about presence/absence of an entity in the current data.
     * 
	 * @returns {boolean} true if entity was found, false if doesn't 
	 * 
	 */
	hasEntity: function ( entityID ) {
		
		for ( var r in this._dataBindings ) {
			
			annotation = this._dataBindings[r];
			
			if ( annotation.topic.value == entityID ) {
				return true;
			}

        }
		
		return false;
	},
	
	/**
     * Retrieves an iterator to navigate between data elements
     * 
	 * @returns {object} Iterator to be used in navigating up data
	 * 
	 * @example 
	 * var i = instance.iterator();
	 * alert('Go to console to see the retrieved data');
	 * console.log(i.next());
	 * 
	 */
	iterator: function() {
		var self = this;
		var keys = [];
		
		for(var key in this._data){
			keys.push(key);
		}
		
		return {
			keys: keys,
			keyIndex: 0,
			
			hasNext: function(){
				return this.keyIndex < this.size();
			},
			
			next: function() {
				return self._data[ this.keys[this.keyIndex++] ];
			},
			
			size: function() {
				return this.keys.length;
			}
		}
		
	},
	
	/**
     * Performs a join operation
	 * 
	 * @param {Biojs.Annotations} a Other annotations object to apply join with by entities. 
	 *
	 * @example 
	 * instance.requestAnnotations("http://biotea.idiginfo.org/pubmedOpenAccess/rdf/PMC2761699");
	 */
	join: function ( a ) {
		
		var result = new Biojs.Annotations( this.opt );
		var dataBindings1 = this._dataBindings;
		var dataBindings2 = a._dataBindings;
		
		result._dataBindings = [];
		
		for ( var i = 0; i < dataBindings1.length; i++ ) {

            // Filters not recognized topics
            try {

            	for ( var j = 0; j < dataBindings2.length; j++ ) {
            		
                	if ( dataBindings1[i].topic.value === dataBindings2[j].topic.value ) {
                		
                		// Add repeated entities from dataBindings1
                		for ( var k = i; k < dataBindings1.length; k++ ) {
                			if ( dataBindings1[i].topic.value === dataBindings1[k].topic.value ) {
                				result._dataBindings.push( dataBindings1[k] );
                			}
                			// Advance counter of dataBindings1
                			i = k;
                		}
                		
                		// Add repeated entities from dataBindings2
                		for ( var k = j; k < dataBindings2.length; k++ ) {
                			if ( dataBindings2[j].topic.value === dataBindings2[k].topic.value ) {
                				result._dataBindings.push( dataBindings2[k] );
                			}
                			// Advance counter of dataBindings2
                			j = k;
                		}
                		
                	}
                }
                
            } catch (e) {
                Biojs.console.log("Topic "+ topicURI + " not recognized. Error: "+ e.message );
            }
		}
		
		if ( this.opt.groupBy == Biojs.Annotations.GROUP_BY_TERM ) {
			result._groupByTerm();
			
		} else if ( this.opt.groupBy == Biojs.Annotations.GROUP_BY_TOPIC ) {
			result._groupByTopic();
		}
		
	    return result;
		
	},

	/**
     * Request the annotations for an URI resource and fills up the cloud with them.
	 * 
	 * @param {string} resourceURI Universal resource identifier 
	 *
	 * @example 
	 * instance.requestAnnotations("http://biotea.idiginfo.org/pubmedOpenAccess/rdf/PMC2761699");
	 */
	requestAnnotations: function ( resourceURI, fnCallback ) {

		//TODO: show loading image
		var self = this;

		var query;
		
		if ( "string" == typeof resourceURI ) {
			query = 
				'SELECT '+
				   'distinct ?annot fn:upper-case(str(?body)) AS ?term '+ 
				   '?topic str(?init) AS ?posInit str(?end) AS ?posEnd ?comment '+
				'WHERE { '+
				      '?annot a aot:ExactQualifier ; '+
				      'ao:annotatesResource <' + resourceURI + '>; '+
				      'ao:body ?body ; '+
				      'ao:hasTopic ?topic ; '+
				      'ao:context ?context . '+
				      '?context rdfs:resource ?resource . '+
				     'OPTIONAL {?context aos:init ?init }. '+
				     'OPTIONAL {?context aos:end ?end } . '+
				     '?resource cnt:chars ?comment .  '
		} else {
			query = 
			'SELECT '+
			   'distinct ?annot fn:upper-case(str(?body)) AS ?term '+ 
			   '?topic str(?init) AS ?posInit str(?end) AS ?posEnd ?comment '+
			'WHERE { '+
			      '?annot a aot:ExactQualifier ; '+
			      'ao:body ?body ; '+
			      'ao:hasTopic ?topic ; '+
			      'ao:context ?context . '+
			      '?context rdfs:resource ?resource . '+
			     'OPTIONAL {?context aos:init ?init }. '+
			     'OPTIONAL {?context aos:end ?end } . '+
			     '?resource cnt:chars ?comment .  '+
			     '{?annot ao:annotatesResource <'+ resourceURI[0] +'> . } UNION '+
			     '{?annot ao:annotatesResource <'+ resourceURI[1] +'> . } ';
		}
		
		if ( this.opt.groupBy == Biojs.Annotations.GROUP_BY_TERM ) {
			query += 'FILTER (regex(str(?' + this.opt.filterBy.field + '), "(' + this.opt.filterBy.value + ')")) . } '
			query += 'ORDER BY ?term ?topic';
			
		} else {
			query += 'FILTER (regex(str(?' + this.opt.filterBy.field + '), "(' + this.opt.filterBy.value + ')")) . } '
			query += 'ORDER BY ?topic ?term';
		}

		this._fetchData( this.opt, query, 'application/json', function( receivedData ) {
			
			if ( "function" == typeof fnCallback ) {
				fnCallback( self._decodeRawData( receivedData ) );
			} else {
				self._decodeRawData( receivedData );
			}

		});
	},
	
	/**
     * Sets the raw data. It replaces the action of requesting annotations to a server
     * 
	 * @param {object} data Raw data
	 * 
	 */
	setRawData: function (data) {
		this._data = data;
	},
	
	/////////////////////////// 'Private' Members /////////////////////////////////////////

	_decodeRawData: function ( rawData ) {

		var result;
		var dataInJSON;
		this._dataBindings = null;
		
		try {
			dataInJSON = jQuery.parseJSON( rawData );
			this._dataBindings = dataInJSON.results.bindings;
			
			if ( this.opt.groupBy == Biojs.Annotations.GROUP_BY_TERM ) {
				result = this._groupByTerm();
				
			} else if ( this.opt.groupBy == Biojs.Annotations.GROUP_BY_TOPIC ) {
				result = this._groupByTopic();
			}

		} catch ( e ) {
			Biojs.console.log("Error decoding response data: " + e.message );
		}   
		
		return result;
	},
	
	// djb2 algorithm (k=33) by Dan Bernstein
    // returns a valid HTML id string from any string 
    _digest: function( str ) {
	    var hash = 5381;
	    for (i = 0; i < str.length; i++) {
	        char = str.charCodeAt(i);
	        hash = ((hash << 5) + hash) + char; /* hash * 33 + c */
	    }
	    return hash;  
    },
    
    _fetchData: function ( opt, query, format, fnCallback ) {
		
		var self = this;
		var dataParams = [];
		
		dataParams.push({ name: "url", value: opt.sparqlUrl });
		dataParams.push({ name: "query", value: escape(query) }); 
		dataParams.push({ name: "format", value: format });
		
		Biojs.console.log("Requesting Query: " + query );
		
		this._request = jQuery.ajax({ 
			url: opt.proxyUrl,
			dataType: "text",
			data: dataParams,
			success: function ( data ) {
				Biojs.console.log("Data received");
				fnCallback.call( self, data );
			}
		});
	},
	
	_filterByMinFrequency: function ( minFreq ) {
		
		var result = this._data;
		
		if ( minFreq > 1) {
			for ( var key in result ) {
				if ( result[key].freq < minFreq ) {
					Biojs.console.log("Filtered item "+ key);
					delete result[key];
				}
			}
		}  
		
		return result;
	},
    
    // Aux. variable to boost searching in topic's map 
    _topicObjectCache: { key: undefined },
    _getTopicObject: function( topicKey ) {

        //topicKey = topicURI.replace(/(#|_|:|\/)([A-Za-z0-9])*$/g,'');
        //topicID = this._digest(topicKey);
        topicObject = undefined;
        
        if ( this._topicObjectCache.key == topicKey ) {
        	topicObject = this._topicObjectCache.value;
        	
        } else if ( this._topicsMap.hasOwnProperty( topicKey ) ) {
        	topicObject = this._topicsMap[ topicKey ];
        	this._topicObjectCache.key = topicKey;
        	this._topicObjectCache.value = topicObject; 
        } 
        
        return topicObject;
    },

	_groupByTerm: function () {

		var result = {};
        var termValue, annotation;
        var topic, topicID, topicObject, topicKey, topicURI;
		
        this._data = result;
        this.opt.groupBy = Biojs.Annotations.GROUP_BY_TERM;
        
        if ( Biojs.Utils.isEmpty(this._dataBindings) ){
        	return result;
        }
		
		for ( r in this._dataBindings ) {

            // Filters not recognized topics
            try {
                annotation = this._dataBindings[r];
                
                topicURI = annotation.topic.value; // URI
                topicKey = topicURI.replace(/(#|_|:|\/)([A-Za-z0-9])*$/g,'');
                entityID = this._digest(topicURI);
                
                termValue = annotation.term.value; // Text
                
                topicObject = this._getTopicObject(topicKey);
                
                topicID = topicObject.shortName;

                // topic present on map?
                if ( !Biojs.Utils.isEmpty(topicObject) ) {
                    //
                    // Create the term first time
                	if ( !result.hasOwnProperty( termValue ) ) {
                		
                		term = {};
                    	term.name = termValue;
                    	term.id = termValue;
                    	term.topics = {}; 
                    	term.freq = 0;
                    	term.comments = [];
                    	term.getEntities = function () {
                    		var result = {};
                    		var entities;
                            
                        	for ( var t in this.topics ) {
                        		entities = this.topics[t].getEntities();
                        		for ( e in entities ) {
                        			if ( entities.hasOwnProperty(e) ) result[e] = entities[e];
                    		    }
                        	}
	                    	
	                    	return result;
	                    };
                    	term.getFrequency = function () {
                    		var result = 0;
                    		var entities;
                            
                        	for ( var t in this.topics ) {
                        		entities = this.topics[t].getEntities();
                        		for ( var e in entities ) {
                        			if ( entities.hasOwnProperty(e) ) result++;
                    		    }
                        	}
	                    	
	                    	return result;
	                    };

                        result[termValue] = term;
                    }
                	
                	term = result[termValue];

                	// Create topic into the term if it's not created yet
                    if ( !term.topics.hasOwnProperty( topicID ) ) {

                    	topic = {};
                    	topic.map = topicObject;
                    	topic.entities = {};
                    	topic.comments = [];
                    	topic.getEntities = function () {
                        	return this.entities;
                        }
                        
                    	term.topics[topicID] = topic;
                    }
                    
                    topic = term.topics[topicID];
                    topic.entities[entityID] = (topicURI);
                    term.comments.push([annotation.comment.value]);
                }

            } catch (e) {
                Biojs.console.log("Topic "+ topicURI + " not recognized. Error: "+ e.message );
            }
        }
		
		// update frequencies
    	for ( var term in result ) {
    		result[term].freq = result[term].getFrequency();
    	}
		
		return this._filterByMinFrequency( this.opt.minFrequency );
	},
    
	_groupByTopic: function() {

		var result = {};
        var termValue, annotation;
        var topic, topicID, topicObject, topicKey, topicURI;
		
        this._data = result;
        
        this.opt.groupBy = Biojs.Annotations.GROUP_BY_TOPIC;
        
        if ( Biojs.Utils.isEmpty(this._dataBindings) ){
        	return result;
        }
		
		for ( r in this._dataBindings ) {

            // Filters not recognized topics
            try {
                annotation = this._dataBindings[r];
                
                topicURI = annotation.topic.value; // URI
                topicKey = topicURI.replace(/(#|_|:|\/)([A-Za-z0-9])*$/g,'');
                entityID = this._digest(topicURI);
                
                termValue = annotation.term.value; // Text
                
                topicObject = this._getTopicObject(topicKey);
                
                topicID = topicObject.shortName;

                // topic present on map?
                if ( !Biojs.Utils.isEmpty(topicObject) ) {
                    //
                    // Create the topic first time
                	if ( !result.hasOwnProperty( topicID ) ) {
                    	topic = {};
                    	topic.map = topicObject;
                    	topic.id = topicID;
                    	topic.name = topicID;
                        topic.terms = {};
                        topic.freq = 0;
                        topic.comments = [];
                        topic.getEntities = function () {
                        	var result = {};
                        	var entities;
                        
                        	for ( var t in this.terms ) {
                        		entities = this.terms[t].getEntities();
                        		for ( e in entities ) {
                        			if ( entities.hasOwnProperty(e) ) result[e] = entities[e];
                    		    }
                        	}
                        	
                        	return result;
                        };
                        topic.getFrequency = function () {
                        	var result = 0;
                        	var entities;
                        
                        	for ( var t in this.terms ) {
                        		entities = this.terms[t].getEntities();
                        		for ( e in entities ) {
                        			if ( entities.hasOwnProperty(e) ) result++;
                    		    }
                        	}
                        	
                        	return result;
	                    };
                        
                        result[topicID] = topic;
                    }
                	
                	topic = result[topicID];

                	// Create term into the topic if it's not created yet
                    if ( !topic.terms.hasOwnProperty( termValue ) ) {
                    	
                    	term = {};
                    	term.value = termValue;
                    	term.entities = {}; 
                    	term.comments = [];
                    	term.getEntities = function () {
                        	return this.entities;
                        }
                    	
                    	topic.terms[termValue] = term;
                    }
                    
                    term = topic.terms[termValue];
                    term.entities[entityID] = (topicURI);
                    topic.comments.push([annotation.comment.value]);
                    
                }

            } catch (e) {
                Biojs.console.log("Topic "+ topicURI + " not recognized. Error: "+ e.message );
            }
        }
		
		// update frequencies
    	for ( var term in result ) {
    		result[term].freq = result[term].getFrequency();
    	}
		
		return this._filterByMinFrequency( this.opt.minFrequency );
	}
	
},{
	
	// Events 
	EVT_ON_DATA_ARRIVED: "onDataArrived",
	
	GROUP_BY_TOPIC: "topic",
	GROUP_BY_TERM: "term",
	
	// Topics map
	TOPIC: {
        //chemical
        "http://purl.obolibrary.org/obo/CHEBI": {
            shortName: "chebi",
            baseUrl: "http://identifiers.org/obo.chebi/CHEBI:",
            prefix: "CHEBI:",
            color: "#D6A100"
        },

        //genes, proteins
        "http://purl.org/obo/owl/GO#GO": {
            shortName: "go",
            baseUrl: "http://identifiers.org/obo.go/GO:",
            prefix: "GO:",
            color: "#0067E6"
        },

        "http://purl.org/obo/owl/PW#PW": {
            shortName: "pw",
            baseUrl: "http://purl.org/obo/owl/PW#PW_",
            prefix: "",
            color: "#00DAE6"
        },

        "http://mged.sourceforge.net/ontologies/MGEDOntology.owl": {
            shortName: "mged",
            baseUrl: "http://mged.sourceforge.net/ontologies/MGEDOntology.owl#",
            prefix: "",
            color: "#6961FF"
        },

        "http://purl.uniprot.org/core": {
            shortName: "uniprot",
            baseUrl: "http://identifiers.org/uniprot/",
            prefix: "",
            color: "#61A8FF"
        },

//		"http://www.uniprot.org/taxonomy": {
//			shortName: "taxonomy",
//			baseUrl: "http://www.uniprot.org/taxonomy/"
//		},

        //drugs
        "http://purl.bioontology.org/ontology/MDDB": {
            shortName: "mddb",
            baseUrl: "http://purl.bioontology.org/ontology/MDDB/",
            prefix: "",
            color: "#FF61A8"
        },

        "http://purl.bioontology.org/ontology/NDDF": {
            shortName: "nddf",
            baseUrl: "http://purl.bioontology.org/ontology/NDDF/",
            prefix: "",
            color: "#C7005A"
        },

        "http://purl.bioontology.org/ontology/NDFRT": {
            shortName: "ndfrt",
            baseUrl: "http://purl.bioontology.org/ontology/NDFRT/",
            prefix: "",
            color: "#FF0F4B"
        },

        //medicine
        "http://purl.bioontology.org/ontology/MEDLINEPLUS": {
            shortName: "medline",
            baseUrl: "http://purl.bioontology.org/ontology/MEDLINEPLUS/",
            prefix: "",
            color: "#329D27"
        },

        "http://purl.bioontology.org/ontology/SNOMEDCT": {
            shortName: "snomed",
            baseUrl: "http://purl.bioontology.org/ontology/SNOMEDCT/",
            prefix: "",
            color: "#AAD864"
        },

        "http://purl.org/obo/owl/SYMP#SYMP": {
            shortName: "symptom",
            baseUrl: "http://purl.org/obo/owl/SYMP#SYMP_",
            prefix: "",
            color: "#A2E7BD"
        },

        "http://purl.bioontology.org/ontology/MDR": {
            shortName: "meddra",
            baseUrl: "http://purl.bioontology.org/ontology/MDR/",
            prefix: "",
            color: "#99CC00"
        },

        "http://purl.bioontology.org/ontology/MSH": {
            shortName: "mesh",
            baseUrl: "http://purl.bioontology.org/ontology/MSH/",
            prefix: "",
            color: "#669980"
        },

        "http://purl.bioontology.org/ontology/OMIM": {
            shortName: "omim",
            baseUrl: "http://identifiers.org/omim/",
            prefix: "",
            color: "#989966"
        },

//		"http://sig.uw.edu/fma": {
//			shortName: "fma",
//			baseUrl: "http://identifiers.org/obo.fma/FMA:"
//		},

        "http://purl.bioontology.org/ontology/ICD9-9": {
            shortName: "icd9",
            baseUrl: "http://identifiers.org/icd/",
            prefix: "",
            color: "#CABDAF"
        },

        "http://www.ifomis.org/bfo/1.1/span": {
            shortName: "obi",
            baseUrl: "http://identifiers.org/obo.obi/OBI_",
            prefix: "",
            color: "#806699"
        },

        "http://berkeleybop.org/obo/UMLS": {
            shortName: "umls",
            baseUrl: "http://berkeleybop.org/obo/UMLS:",
            prefix: "",
            color: "#CC00FF"
        },

        //plants
        "http://purl.bioontology.org/ontology/PO": {
            shortName: "po",
            baseUrl: "http://purl.bioontology.org/ontology/PO/",
            prefix: "",
            color: "#007D00"
        },

        //thesaurus
        "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl": {
            shortName: "ncithesaurus",
            baseUrl: "http://ncicb.nci.nih.gov/xml/owl/EVS/Thesaurus.owl",
            prefix: "",
            color: "#9C38FF"
        },

        //organisms
        "http://purl.org/obo/owl/NCBITaxon#NCBITaxon": {
            shortName: "ncbitaxon",
            baseUrl: "http://identifiers.org/taxonomy/",
            prefix: "",
            color: "#5E00BD"
        }
    }
	
});